#ifndef SOUND_H
#define SOUND_H

#include "Resource.h"

namespace Cvekas {

/// Abstract sound
class Sound : public Resource
{
public:
	/// Constructor
	/// \param name Sound name
	/// \param id Resource ID
	/// \param filename File, which contains sound data
	Sound(const std::string& name, ResourceId id, const std::string& filename)
		: Resource(name, id), filename(filename)
	{
	}

	/// Destructor
	virtual ~Sound() {};

	/// Plays or resumes paused sound.
	/// \param loop If true, sound will restart from the beginning once finished playing.
	virtual void play(bool loop = false) = 0;

	/// Stops sound. Does nothing if sound is not playing.
	virtual void stop() = 0;

	/// Pauses sound. It can be resumed by play()
	virtual void pause() = 0;

	/// Returns length of sound in seconds
	virtual float getLength() = 0;

	/// Returns current playing cursor position in seconds
	virtual float getPosition() = 0;

	/// Sets playing cursor position. Throws exception if t is negative or greater than sound length.
	virtual void setPosition(float t) = 0;

private:
	const std::string filename;
};

typedef boost::shared_ptr<Sound> SoundPtr;

/// \brief %Sound, which resides in memory all the time
///
/// Multiple sounds of the same %SoundSample instance can be played at the same
/// time, but stop(), pause(), getPosition(), setPosition() work only on the 
/// last played sound.
class SoundSample : public Sound
{
public:
	SoundSample(const std::string& name, ResourceId id, const std::string& filename);
	virtual ~SoundSample();

	/// Looping is ignored for sound samples
	virtual void play(bool loop = false);
	virtual void stop();
	virtual void pause();

	virtual float getLength();
	virtual float getPosition();
	virtual void setPosition(float t);

private:
	HSAMPLE handle;
	HCHANNEL last_channel;

	float start_pos;
};

/// %Sound, which is streamed from hard disk
class SoundStream : public Sound
{
public:
	SoundStream(const std::string& name, ResourceId id, const std::string& filename);
	virtual ~SoundStream();

	virtual void play(bool loop = false);
	virtual void stop();
	virtual void pause();

	virtual float getLength();
	virtual float getPosition();
	virtual void setPosition(float t);

private:
	HSTREAM handle;
};

} // namespace

#endif